import Taro, {request} from "@tarojs/taro"
import {axios} from 'taro-axios'
import {ServerData} from './server.interface'
import {APP_V, BASE_URL, BD_KEY, P_KEY, TARO_ENV} from '../constants/api'
import {user} from './user.service'
import {GetRequest, getTokenFromCookies} from "./tools";

axios.defaults.transformRequest = [function (data) {
  let src = ''
  for (const item in data) {
    src += encodeURIComponent(item) + '=' + encodeURIComponent(data[item]) + '&'
  }
  return src
}]
const requests = axios.create({
  baseURL: BASE_URL,
  timeout: 20000
})

const lxCreateLink = [
  'msvc-order/v2/group/paytoken/',
  'msvc-order/v2/order/paytoken/',
  'msvc-order/v2/order/pay/',
  'msvc-order/v2/group/pay/',
  'msvc-order/v2/order/confirm',
  'msvc-order/v2/cart/pay',
  'msvc-order/v2/order/payinfo',
  'msvc-order/v2/group/create',
  'msvc-order/v2/order/create',
  'api/v3/order/creatRecharge',
  'api/v3/orderPay/getWeixinPayPackageForRecharge',
]

//添加拦截
requests.interceptors.request.use(config => {
  config.headers = http.getHeader({}, config.url)
  return config
})

requests.interceptors.response.use(res => {
  return res
}, error => {
  console.log(JSON.stringify(error))
  return error.response;
})

const city = Taro.getStorageSync('city');

class HttpClass {
  header = {'Content-Type': 'application/x-www-form-urlencoded'};
  siteHash = ''
  beKey = ''
  mpkey = ''
  areaId = (city && city.region_id) || 0

  async get<T = any>(url: string, param?: { [key: string]: string | number }): Promise<T | boolean> {
    const link = this.url(url, param);
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url: link,
        method: 'get',
      })
      return await this.showErrMsg(ret)
    } else {
      const ret = await Taro.request({
        method: 'GET',
        url: link,
        header: this.getHeader(),
      })
      return await this.showErrMsg(ret)
    }
  }

  async carGet<T = any>(url: string, param?: { [key: string]: string | number }): Promise<T | boolean> {
    const link = this.url(url, param);
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url: link,
        method: 'get',
      })
      return await this.showCarErrMsg(ret)
    } else {
      const ret = await Taro.request({
        method: 'GET',
        url: link,
        header: this.getHeader(),
      })
      return await this.showCarErrMsg(ret)
    }
  }

  async MGet<T = any>(url: string, param?: { [key: string]: string | number }): Promise<T | boolean> {
    const link = this.url(url, param);
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url: link,
        method: 'get',
      })
      return await this.showMErrMsg(ret)
    } else {
      const ret = await Taro.request({
        method: 'GET',
        url: link,
        header: this.getHeader(),
      })
      return await this.showMErrMsg(ret)
    }
  }

  async HGet<T = any>(url: string, param?: { [key: string]: string | number }): Promise<T | boolean> {
    const link = this.url(url, param);
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url: link,
        method: 'get',
      })
      return await this.showHErrMsg(ret)
    } else {
      const ret = await Taro.request({
        method: 'GET',
        url: link,
        header: this.getHeader(),
      })
      return await this.showHErrMsg(ret)
    }
  }

  async post<T = any>(url: string, data: { [key: string]: any }, param?: { [key: string]: string | number }, header?: { [key: string]: any }): Promise<T | false> {
    if (url && url.endsWith('updateUserShareDate')) {
      if (!await user.checkLogin()) {
        return false
      }
    }
    const location = Taro.getStorageSync('locationData');
    if (location) {
      data.lng = location.longitude || '';
      data.lat = location.latitude || '';
    }
    let ret = {};
    if (process.env.TARO_ENV === 'h5') {
      // 灵锡账号合并APP++header
      if (process.env.P_ENV === 'lx' && url && lxCreateLink.some(item => url && (url.startsWith(BASE_URL + item) || url.indexOf(item) > -1))) {
        ret = await requests({
          url: this.url(url, param),
          method: 'post',
          data: {...data, areaId: this.areaId},
          header: this.getHeader({}, url),
        })
      }else {
        ret = await requests({
          url: this.url(url, param),
          method: 'post',
          data: {...data, areaId: this.areaId},
        })
      }
      return await this.showErrMsg(ret)
    } else {
      const ret = await Taro.request({
        method: 'POST',
        url: this.url(url, param),
        data: {...data, areaId: this.areaId},
        header: this.getHeader(header, url),
      })
      return await this.showErrMsg(ret)
    }
  }

  async postL<T = any>(url: string, data: { [key: string]: any }, param?: { [key: string]: string | number }, header?: { [key: string]: any }): Promise<T | false> {
    if (url && url.endsWith('updateUserShareDate')) {
      if (!await user.checkLogin()) {
        return false
      }
    }
    let location
    if (TARO_ENV === 'h5' && process.env.NODE_ENV !== 'development') {
      location = await new Promise((resolve) => {
        wx.getLocation({
          type: 'wgs84',
          success: function (res) {
            location = {
              latitude: res.latitude,
              longitude: res.longitude,
            }
            resolve(location)
          },
        })
      })
    } else {
      location = {}
    }
    if (location) {
      data.lng = location.longitude || '';
      data.lat = location.latitude || '';
    }
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url: this.url(url, param),
        method: 'post',
        data: {...data, areaId: this.areaId},
      })
      return await this.showErrMsg(ret)
    } else {
      const ret = await Taro.request({
        method: 'POST',
        url: this.url(url, param),
        data: {...data, areaId: this.areaId},
        header: this.getHeader(header),
      })
      return await this.showErrMsg(ret)
    }
  }

  async MPost<T = any>(url: string, data: { [key: string]: any }, param?: { [key: string]: string | number }, header?: { [key: string]: any }): Promise<T | false> {
    const location = Taro.getStorageSync('locationData');
    if (location) {
      data.lng = location.longitude || '';
      data.lat = location.latitude || '';
    }
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url: this.url(url, param),
        method: 'post',
        data: {...data, areaId: this.areaId},
      })
      return await this.showMErrMsg(ret)
    } else {
      const ret = await Taro.request({
        method: 'POST',
        url: this.url(url, param),
        data: {...data, areaId: this.areaId},
        header: this.getHeader(header),
      })
      return await this.showMErrMsg(ret)
    }
  }

  async HPost<T = any>(url: string, data: { [key: string]: any }, offToast?: boolean, param?: { [key: string]: string | number }, header?: { [key: string]: any }): Promise<T | false> {
    return new Promise(async resolve => {
      let ret: any = {};
      const location = Taro.getStorageSync('locationData');
      if (location) {
        data.lng = location.longitude || '';
        data.lat = location.latitude || '';
      }
      if (process.env.TARO_ENV === 'h5') {
        ret = await requests({
          url,
          method: 'post',
          data: {...data}
        })
      } else {
        ret = await Taro.request({
          method: 'POST',
          url: this.url(url, param),
          data,
          header: this.getHeader(header),
        })
      }
      if (!ret) {
        resolve(false);
      }
      const statusCode = ret && (ret.statusCode || ret.status)
      if (statusCode == 200) {
        resolve(ret.data || false);
      } else if (statusCode == 400) {
        if (!offToast) {
          if (ret.data.status) {
            return resolve(ret.data.status)
          }
          let str = ''
          if (ret.data.message) {
            if (ret.data.message.message) {
              str = ret.data.message.message
            } else {
              str = ret.data.message
            }
          } else {
            str = ret.data.msg
          }
          Taro.showToast({
            title: (str || '网络请求错误,稍后再试'),
            icon: 'none',
            duration: 3000
          });
          resolve(false)
        } else {
          resolve(ret.data || false);
        }
      } else if (statusCode == 401) {
        if (process.env.P_ENV === 'lx') {
          if (process.env.TARO_ENV === 'h5') {
            document.cookie = ''
          }
          Taro.removeStorageSync('user')
        }
        Taro.hideLoading()
        user.jumpLogin()
        resolve(false)
      } else if (statusCode == 429) {
        if (!offToast) {
          Taro.showToast({
            title: '太多人抢了，请先歇会再点',
            icon: 'none',
          });
        }
        resolve(false)
      } else if (statusCode == 500) {
        if (!offToast) {
          Taro.showToast({
            title: '矮油,开小差啦...',
            icon: 'none'
          })
        }
        resolve(false)
      } else {
        if (!offToast) {
          if (ret.data.msg || ret.data.message) {
            resolve(ret.data)
          }
        }
      }
    })
  }

  async postCondition<T = any>(url: string, data: { [key: string]: any }, param?: { [key: string]: string | number }, header?: { [key: string]: any }): Promise<T | false> {
    return new Promise(async resolve => {
      let ret = {};
      const location = Taro.getStorageSync('locationData');
      if (location) {
        data.lng = location.longitude || '';
        data.lat = location.latitude || '';
      }
      if (process.env.TARO_ENV === 'h5') {
        ret = await requests({
          url: this.url(url, param),
          method: 'post',
          data: {...data}
        })
      } else {
        ret = await Taro.request({
          method: 'POST',
          url: this.url(url, param),
          data,
          header: this.getHeader(header),
        })
      }
      const statusCode = ret.statusCode || ret.status
      if (statusCode !== 200) {
        if (statusCode == 400) {
          Taro.showToast({
            title: ret.data.message || ret.data.msg || '网络请求错误,稍后再试',
            icon: 'none',
          });
        } else if (statusCode == 401) {
          if (process.env.P_ENV === 'lx') {
            if (process.env.TARO_ENV === 'h5') {
              document.cookie = ''
            }
            Taro.removeStorageSync('user')
          }
          Taro.hideLoading()
          user.jumpLogin()
          resolve(false)
        } else if (statusCode == 204) {//options请求
          resolve(false)
        } else {
          Taro.showToast({
            title: (ret.data.message || ret.data.msg || '网络请求错误,稍后再试'),
            icon: 'none',
          });
        }
        resolve(false)
      } else {
        resolve(ret.data || false);
      }
    })
  }

  async postCar<T = any>(url: string, data: { [key: string]: any }, param?: { [key: string]: string | number }, header?: { [key: string]: any }, duration = 2000): Promise<T | false> {
    return new Promise(async resolve => {
      let ret = {};
      const location = Taro.getStorageSync('locationData');
      if (location) {
        data.lng = location.longitude || '';
        data.lat = location.latitude || '';
      }
      if (process.env.TARO_ENV === 'h5') {
        // 灵锡账号合并APP+header
        if (process.env.P_ENV === 'lx' && url && lxCreateLink.some(item => url && (url.startsWith(BASE_URL + item) || url.indexOf(item) > -1))) {
          ret = await requests({
            url: this.url(url, param),
            method: 'post',
            data,
            header: this.getHeader({}, url),
          })
        }else {
          ret = await requests({
            url: this.url(url, param),
            method: 'post',
            data,
          })
        }
      } else {
        ret = await Taro.request({
          method: 'POST',
          url: this.url(url, param),
          data,
          header: this.getHeader(header),
        })
      }
      const statusCode = ret.statusCode || ret.status
      if (statusCode == 200) {
        resolve(ret.data.data || true);
      } else if (statusCode == 400) {
        Taro.showToast({
          duration,
          title: (ret.data.message || ret.data.msg || '网络请求错误,稍后再试'),
          icon: 'none',
        });
        resolve(false)
      } else if (statusCode == 401) {
        if (process.env.P_ENV === 'lx') {
          if (process.env.TARO_ENV === 'h5') {
            document.cookie = ''
          }
          Taro.removeStorageSync('user')
        }
        Taro.hideLoading()
        user.jumpLogin()
        resolve(false)
      } else if (statusCode == 429) {
        Taro.showToast({
          duration,
          title: '太多人抢了，请先歇会再点',
          icon: 'none',
        });
        resolve(false)
      } else if (statusCode == 500) {
        Taro.showToast({
          duration,
          title: '矮油,开小差啦...',
          icon: 'none'
        })
        resolve(false)
      } else {
        if (ret.data.msg || ret.data.message) {
          Taro.showToast({
            duration,
            title: (ret.data.msg || ret.data.message || ''),
            icon: 'none'
          })
        }
      }
    })
  }

  async postNGL<T = any>(url: string, data: { [key: string]: any }, param?: { [key: string]: string | number }, header?: { [key: string]: any }): Promise<T | false> {
    if (url && url.endsWith('updateUserShareDate')) {
      if (!await user.checkLogin()) {
        return false
      }
    }
    const location = Taro.getStorageSync('locationData');
    if (location) {
      data.lng = location.longitude || '';
      data.lat = location.latitude || '';
    }
    let ret = false;
    if (process.env.TARO_ENV === 'h5') {
      ret = await requests({
        url: this.url(url, param),
        method: 'post',
        data: {...data},
      })
    } else {
      ret = await Taro.request({
        method: 'POST',
        url: this.url(url, param),
        data: {...data},
        header: this.getHeader(header, url),
      })
    }
    const statusCode = ret.statusCode || ret.status
    if(statusCode === 200) ret = ret.data.data.data || ret.data.data;
    return ret;
  }

  async showHErrMsg<T = string>(data: request.SuccessCallbackResult<ServerData<T>>): Promise<T | false> {
    return new Promise(async (resolve) => {
      const statusCode = data && (data.statusCode || data.status)
      if (statusCode == 200) {
        resolve(data.data);
      } else if (statusCode == 400) {
        Taro.showToast({
          title: '' + data.data.message || '' + data.data.msg,
          icon: 'none',
        });
        resolve(false)
      } else if (statusCode == 401) {
        if (process.env.P_ENV === 'lx') {
          if (process.env.TARO_ENV === 'h5') {
            document.cookie = ''
          }
          Taro.removeStorageSync('user')
        }
        Taro.hideLoading()
        user.jumpLogin()
        resolve(false)
      } else if (statusCode == 429) {
        Taro.showToast({
          title: '太多人抢了，请先歇会再点',
          icon: 'none',
        });
        resolve(false)
      } else if (statusCode == 500) {
        Taro.showToast({
          title: '矮油,开小差啦...',
          icon: 'none'
        })
        resolve(false)
      } else if (statusCode == 204) {//options请求
        resolve(false)
      } else {
        if (data && (data.data.msg || data.data.message)) {
          Taro.showToast({
            title: (data.data.msg || data.data.message || ''),
            icon: 'none'
          })
        }
      }
    })
  }

  async showMErrMsg<T = string>(data: request.SuccessCallbackResult<ServerData<T>>): Promise<T | false> {
    return new Promise(async (resolve) => {
      const statusCode = data && (data.statusCode || data.status)
      if (statusCode == 200) {
        if (data.data && data.data.data && (!!data.data.data.labelArray || !!data.data.data.custom)) {
          resolve(data.data);
        } else {
          resolve(data.data.data.data);
        }
      } else if (statusCode == 400) {
        Taro.showToast({
          title: '' + data.data.message || '' + data.data.msg,
          icon: 'none',
        });

        resolve(false)
      } else if (statusCode == 401) {
        if (process.env.P_ENV === 'lx') {
          if (process.env.TARO_ENV === 'h5') {
            document.cookie = ''
          }
          Taro.removeStorageSync('user')
        }
        Taro.hideLoading()
        user.jumpLogin()
        resolve(false)
      } else if (statusCode == 429) {
        Taro.showToast({
          title: '太多人抢了，请先歇会再点',
          icon: 'none',
        });
        resolve(false)
      } else if (statusCode == 500) {
        Taro.showToast({
          title: '矮油,开小差啦...',
          icon: 'none'
        })
        resolve(false)
      } else {
        if (data.data.msg || data.data.message) {
          Taro.showToast({
            title: (data.data.msg || data.data.message || ''),
            icon: 'none'
          })
        }
        resolve(false)
      }
    })
  }

  async showCarErrMsg<T = string>(data: request.SuccessCallbackResult<ServerData<T>>): Promise<T | false> {
    return new Promise(async (resolve) => {
      const statusCode = data && (data.statusCode || data.status)
      if (statusCode == 200) {
        resolve(data.data.data);
      } else if (statusCode == 400) {
        Taro.showToast({
          title: '' + data.data.message || '' + data.data.msg,
          icon: 'none',
        });
        resolve(false)
      } else if (statusCode == 401) {
        if (process.env.P_ENV === 'lx') {
          if (process.env.TARO_ENV === 'h5') {
            document.cookie = ''
          }
          Taro.removeStorageSync('user')
        }
        Taro.hideLoading()
        user.jumpLogin()
        resolve(false)
      } else if (statusCode == 429) {
        Taro.showToast({
          title: '太多人抢了，请先歇会再点',
          icon: 'none',
        });
        resolve(false)
      } else if (statusCode == 500) {
        Taro.showToast({
          title: '矮油,开小差啦...',
          icon: 'none'
        })
        resolve(false)
      } else {
        if (data.data.msg || data.data.message) {
          Taro.showToast({
            title: (data.data.msg || data.data.message || ''),
            icon: 'none'
          })
        }
      }
    })
  }

  async showErrMsg<T = string>(data: request.SuccessCallbackResult<ServerData<T>>): Promise<T | false> {
    return new Promise(async (resolve) => {
      const statusCode = data && (data.statusCode || data.status)
      if (statusCode !== 200) {
        if (statusCode == 429) {
          Taro.showToast({
            title: "太多人抢了，请先歇会再点",
            icon: 'none',
          });
        } else if (statusCode == 401) {
          if (process.env.P_ENV === 'lx') {
            if (process.env.TARO_ENV === 'h5') {
              document.cookie = ''
            }
            Taro.removeStorageSync('user')
          }
          Taro.hideLoading()
          user.jumpLogin()
          resolve(false)
        } else {
          Taro.showToast({
            title: '网络请求错误',
            icon: 'none',
          });
        }
        resolve(false)
      } else if (!data.data.isOk) {
        // 秒杀列表海报数据
        if(data.data && data.data.data && data.data.data.url && data.data.data.miniappUrl) {
          resolve(data.data);
        }
        if (data.data.msg === '预约已结束' || data.data.msg === '预约未开始') {
          data.data.data.msg = data.data.msg
          resolve(data.data.data);
        }
        if (data.data.validTicket) {
          Taro.showModal({
            title: '提示',
            content: data.data.data,
            showCancel: false
          })
        }
        if (data.data.data !== '400') {
          const msg = data.data.msg || data.data.message || ''
          if (msg && msg !== '未找到相关信息' && msg !== '平台不能为空') {
            Taro.showToast({
              title: msg,
              icon: 'none'
            })
          }
        }
        resolve(false)
      } else {
        resolve(data.data.data);
      }
    })
  }

  url(url: string, param?: { [key: string]: string | number }): string {
    if (/^\/+/.test(url)) {
      url = url.slice(1)
    }
    let service = '';
    if (process.env.TARO_ENV === 'weapp') {
      const extConfig = Taro.getExtConfigSync();
      if (typeof (extConfig['service']) != "undefined" && extConfig['service'] != 'null' && extConfig['service'] != '') {
        service = extConfig['service'] + '/'
      }
    }
    let path
    if (url.search(/(http|https):\/\//) !== 0) {
      path = BASE_URL + service + url
    } else {
      path = url
    }
    const location = Taro.getStorageSync('locationData');
    if (param) {
      const parameterArr: any[] = [];
      Object.keys(param).map(key => {
        parameterArr.push({
          key,
          val: param[key] !== undefined ? encodeURIComponent(param[key].toString()) : '',
        });
      })
      const parameterStr = parameterArr.map(v => `${v.key}=${v.val}`).join('&');
      if (parameterStr) {
        if (path.indexOf('?') === -1) {
          path += '?' + parameterStr;
        } else {
          path += '&' + parameterStr;
        }
      }
    }
    if (path.indexOf('?') == -1) {
      path += '?lng=' + (location.longitude || '') + '&lat=' + (location.latitude || '');
      path += '&areaId=' + this.areaId
    } else {
      path += '&lng=' + (location.longitude || '') + '&lat=' + (location.latitude || '');
      path += '&areaId=' + this.areaId
    }
    return path
  }

  getToken() {
    const userInfo = Taro.getStorageSync('user')
    if (process.env.TARO_ENV === 'h5') {
      const token = getTokenFromCookies(document.cookie, userInfo)
      return token || user.token || userInfo.token || ''
    } else {
      return user.token || userInfo.token || ''
    }
  }

  getHeader(data: any = {}, url = '') {
    const header = {
      ...this.header,
      ...data,
    };
    const userInfo = Taro.getStorageSync('user')
    const sKey = Taro.getStorageSync('sKey')
    header['apiVersion'] = '3.0'
    header['codeType'] = process.env.TARO_ENV
    if (process.env.TARO_ENV === 'tt') {
      header['from'] = 'bytedance'
      header['codeType'] = 'douyin'
    }
    // 灵锡账号合并APP++header
    if (process.env.TARO_ENV === 'h5' && process.env.P_ENV === 'lx' && url) {
      if (lxCreateLink.some(item => url && (url.startsWith(BASE_URL + item) || url.indexOf(item) > -1))) {
        header['codeType'] = 'lingxi-app'
      }
    }
    if (sKey) {
      header['s-key'] = sKey;
    }
    if (process.env.TARO_ENV === 'h5') {
      const token = getTokenFromCookies(document.cookie, userInfo)
      header['token'] = token || user.token || userInfo.token || ''
      header['p-key'] = this.getSiteHash()
      header['mp-key'] = this.getMpKey()
    } else {
      header['appVersion'] = APP_V
      header['token'] = user.token || userInfo.token || ''
      header['p-key'] = this.getSiteHash()
    }
    // header['token'] = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ7XCJ1c2VySWRcIjoxMTY2OTg0fSIsImV4cCI6MTY2OTY5NjAxNiwiaWF0IjoxNjY5NjkyNDE2fQ.cVO84Mp6mV-yBDD6ffi19KPkJerMmESzvme5MXo6xCY'
    const pages = Taro.getStorageSync('pages')
    if (pages.length > 0) {
      header['vc_request'] = pages[pages.length - 1]
    }
    if (pages.length > 1) {
      header['vc_referer'] = pages[pages.length - 2]
    }
    const sessionObj = Taro.getStorageSync("sessionObj");
    if (typeof (sessionObj) != "undefined" && null != sessionObj) {
      if (typeof (sessionObj.sessionId) != "undefined" && null != sessionObj.sessionId) {
        header['vc_session'] = sessionObj.sessionId
      }
      if (typeof (sessionObj.step) != "undefined" && null != sessionObj.step) {
        header['vc_step'] = sessionObj.step
      }
    }
    if (process.env.TARO_ENV === 'tt') {
      header['bd-key'] = this.getBDKey()
    }
    return header;
  }

  getBDKey(){
    if (this.beKey) return this.beKey
    const extConfig = Taro.getExtConfigSync();
    if (JSON.stringify(extConfig['extConfig']) === '{}') {
      this.beKey = BD_KEY
    } else {
      this.beKey = extConfig['extConfig']['bd-key'] || '';
    }
  }

  getSiteHash() {
    if (this.siteHash) return this.siteHash
    if (process.env.TARO_ENV === 'weapp') {
      const extConfig = Taro.getExtConfigSync();
      this.siteHash = extConfig['p-key'] || '';
    } else if (process.env.TARO_ENV === 'tt') {
      const extConfig = Taro.getExtConfigSync();
      if (JSON.stringify(extConfig['extConfig']) === '{}') {
        this.siteHash = P_KEY
      } else {
        this.siteHash = extConfig['extConfig']['p-key'] || '';
      }
    } else {
      const query: any = Taro.getCurrentInstance().router.params;
      const extConfig = Taro.getStorageSync('user');
      this.siteHash = extConfig.pkey || query.pkeys || '';
    }
    return this.siteHash
  }

  getMpKey() {
    if (this.mpkey) {
      if (typeof (this.mpkey) == "undefined" || this.mpkey == 'null') {
        this.mpkey = '';
      }
      return this.mpkey;
    }
    if (process.env.TARO_ENV === 'h5') {
      const extConfig = Taro.getStorageSync('user');
      this.mpkey = extConfig.mpkey;
    }
    if (typeof (this.mpkey) == "undefined" || null == this.mpkey || this.mpkey == 'null') {
      this.mpkey = '';
    }
    return this.mpkey
  }
}

export const http = new HttpClass();
